package org.cuijq.thinking.in.spring.dependency.lookup;

import org.cuijq.thinking.in.spring.ioc.domain.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author by CuiJQ
 * @Classname TypeSaftyDepedencyLookupDemo
 * @Description TypeSaftyDepedencyLookupDemo Description
 * 类型安全依赖查找
 * @Date 2021/6/28 16:58
 */
public class TypeSaftyDepedencyLookupDemo {

  public static void main(String[] args) {
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
    ac.register(TypeSaftyDepedencyLookupDemo.class);
    ac.refresh();
    displayBeanFactoryGetBean(ac);
    displayObjectFactoryGetObject(ac);

    //安全的
    displayObjectProviderIfAvaliable(ac);

    displayListableBeanFactoryGetBeansOfType(ac);

    displayObjectProviderStreamOps(ac);
    ac.close();
  }

  private static void displayObjectProviderStreamOps(AnnotationConfigApplicationContext ac) {
    ObjectProvider<User> userObjectProvider =ac.getBeanProvider(User.class);
    printBeansException("displayObjectProviderStreamOps",()->{
      userObjectProvider.forEach(System.out::println);
    });
  }

  private static void displayListableBeanFactoryGetBeansOfType(ListableBeanFactory listableBeanFactory) {
    printBeansException("displayListableBeanFactoryGetBeansOfType",()->{
      listableBeanFactory.getBeansOfType(User.class);
    });
  }

  private static void displayObjectProviderIfAvaliable(AnnotationConfigApplicationContext ac) {
    ObjectProvider<User> userObjectProvider =ac.getBeanProvider(User.class);
    printBeansException("displayObjectFactoryGetObject",()->{
      userObjectProvider.getIfAvailable();
    });
  }

  public static void displayObjectFactoryGetObject(AnnotationConfigApplicationContext ac){
    ObjectFactory<User> userObjectFactory =ac.getBeanProvider(User.class);
    printBeansException("displayObjectFactoryGetObject",()->{
      userObjectFactory.getObject();
    });

  }
  public static void displayBeanFactoryGetBean(BeanFactory beanFactory){
      printBeansException("displayBeanFactoryGetBean",()->{
        beanFactory.getBean(User.class);
      });
  }

  private static void printBeansException(String source,Runnable runnable){
    System.err.println("==============================");
    System.err.println("from:"+source);
    try {
      runnable.run();
    }catch (BeansException ex){
      ex.printStackTrace();
    }
  }
}
